import { Agent } from "./Agent";
import * as Debug from "./Debug";
import I, { Styles } from "./Interactive";
import { Interpreter } from "./StdCharacter";
import { N, NUtils, Pronoun } from "./NarrativeBase";
import { Narrative } from "./NarrativeContext";
import { TestRoomA } from "./TestScene";
import { U } from "./Util";
import { UniversalImperatives, World, type ScheduledProcess } from "./WorldBase";

export const VERSION_STORY = 'pre-alpha test 0.1';

export let protagonist = new Agent('O', Pronoun.You, TestRoomA);
let interpreter = new Interpreter(protagonist);
let narrative = new Narrative();

export async function Main() {
    narrative.context.setPronoun(Pronoun.You, protagonist);
    narrative.context.freeIndirectSubject.add(protagonist);

    I.printCentered(`
                          ___                    
(   /'_      _      _ _  (_ _ '_ __/_ _ _        
|/|//(-  ((/(-/)/) (///) / (-/(-/ /(/(/(- .  .  .
                                    _/           \n`, false);
    I.printCentered("测试程序：*“犹如在节日里...”*\n\n", true, Styles.Meta);

    await I.getKey("\n");
    World.schedule.addAction(protagonist.healthCoroutine(), protagonist);
    U.thought(protagonist, N.text('你在一个你不认识的地方睁开眼睛。')).submitMomentary();
    doProcess(interpreter.describeZone());
    while (true) {
        I.setHeader(protagonist.parentZone.name);
        let input = await I.input("\n> ");
        await doProcess(interpreter.parseCommand(input, narrative.context));
    }
}

function printHistory() {
    const collection = protagonist.memory.filter(narrative.context);
    protagonist.memory.markAsOld();
    if (collection.length == 0) return;
    let lastGroup = collection[0][1][0].group;
    for (const group of collection) {
        let sentences = group[1];
        sentences = narrative.optimize(sentences);
        narrative.updatePronouns(sentences);
        const confabulation = sentences.map((x) => {
            let prefix = '';
            if (x.group != lastGroup) {
                prefix = '\n\n';
                lastGroup = x.group;
            }
            return prefix + narrative.confabulate(x);
        }).join('');
        switch (group[0]) {
        case "meta":
            I.print(confabulation, true, Styles.Meta);
            break;
        case "annotation":
            I.print(confabulation, true, Styles.Comment);
            break;
        case 'narrative':
            I.print(confabulation);
            break;
        default:
            Debug.assert(false);
        }
    }
    I.print('\n');
}

async function doProcess(x: ScheduledProcess) {
    // I.print(`(${U.timeString()}) `, false, Styles.Comment)
    let entry = World.schedule.addAction(x, protagonist);
    while (!entry.delete) {
        let c = UniversalImperatives.passTimeUntil(entry.nextTime);
        let input = '';
        while (true) {
            Debug.checkRegister();
            let result = c.next(input);
            if (result.done) break;
            printHistory();
            I.print(result.value, true, Styles.Meta);
            input = await I.input();
        }
    }
    printHistory();
}